package org.example.controller.common.permission;

import lombok.extern.slf4j.Slf4j;
import org.example.controller.common.constants.ControllerClassConstants;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 权限工具类
 */
@Slf4j
public class PermissionUtils {

    /**
     * 获取所有的权限信息
     */
    public static List<PermissionObject> GetAllPermissions() throws IllegalAccessException, ClassNotFoundException {
        Class<ControllerClassConstants> controllerPackageConstantsClass = ControllerClassConstants.class;
        Field[] declaredFields = controllerPackageConstantsClass.getDeclaredFields();
        List<PermissionObject> permissionObjectList = new ArrayList<>();
        List<Class<?>> nextClassList = new ArrayList<>();
        PermissionObject permissionObject = null;
        for (Field declaredField : declaredFields) {
            String fieldVal = (String) declaredField.get(null);
            Class<?> realClass = Class.forName(fieldVal);
            PermissionControl classAnnotation = realClass.getAnnotation(PermissionControl.class);
            String classParent = classAnnotation.Parent();
            if (!classParent.equals("parent")) {
                nextClassList.add(realClass);
            } else {
                permissionObject = new PermissionObject();
                permissionObject.setName(classAnnotation.Name());
                permissionObject.setOrder(classAnnotation.Order());
                permissionObject.setPermissionList(PermissionUtils.handleMethodPermission(realClass));
                permissionObjectList.add(permissionObject);
            }
        }
        List<String> firstPermissionList = new ArrayList<>();
        for (PermissionObject object : permissionObjectList) {
            firstPermissionList.add(object.getName());
        }
        for (Class<?> realClass : nextClassList) {
            PermissionControl classAnnotation = realClass.getAnnotation(PermissionControl.class);
            String classParent = classAnnotation.Parent();
            if (!firstPermissionList.contains(classParent)) {
                permissionObject = new PermissionObject();
                permissionObject.setName(classParent);
                permissionObject.setOrder(999);
                firstPermissionList.add(classParent);
                permissionObjectList.add(permissionObject);
            }
            for (PermissionObject object : permissionObjectList) {
                if (object.getName().equals(classParent)) {
                    permissionObject = new PermissionObject();
                    permissionObject.setName(classAnnotation.Name());
                    permissionObject.setOrder(classAnnotation.Order());
                    permissionObject.setPermissionList(PermissionUtils.handleMethodPermission(realClass));
                    List<PermissionObject> children = object.getChildren();
                    if (children == null) {
                        List<PermissionObject> temp = new ArrayList<>();
                        temp.add(permissionObject);
                        object.setChildren(temp);
                    } else {
                        children.add(permissionObject);
                        object.setChildren(children);
                    }
                }
            }
        }
        Collections.sort(permissionObjectList);
        return permissionObjectList;
    }

    // 对指定类的方法的处理
    private static List<PermissionObject> handleMethodPermission (Class<?> realClass) {
        List<PermissionObject> permissionList = new ArrayList<>();
        Method[] methods = realClass.getDeclaredMethods();
        PermissionObject permissionObject = null;
        for (Method method : methods) {
            boolean annotationPresent = method.isAnnotationPresent(PermissionControl.class);
            if (annotationPresent) {
                PermissionControl methodAnnotation = method.getAnnotation(PermissionControl.class);
                permissionObject = new PermissionObject();
                permissionObject.setName(methodAnnotation.Name());
                permissionObject.setOrder(methodAnnotation.Order());
                permissionList.add(permissionObject);
            }
        }
        Collections.sort(permissionList);
        return permissionList;
    }
}
